package com.fjwt.gz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.db.bo.ActivityAwardAndSettingBo;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.HelpRecordDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.HelpRecordVO;
import com.fjwt.gz.service.mapper.HelpRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 活动助力分享记录表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class HelpRecordService extends ServiceImpl<HelpRecordMapper, HelpRecordEntity> {

    @Autowired
    private HelpRecordMapper helpRecordMapper;
    @Autowired
    private ActivityHelpService activityHelpService;
    @Autowired
    private ActivityShareService activityShareService;
    @Autowired
    private HelpRecordService shareRecordService;
    @Autowired
    private SendAwardService sendAwardService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private FansUserService fansUserService;
    @Autowired
    private ActivityAwardService activityAwardService;
    @Autowired
    private FansService fansService;
    @Autowired
    private AwardCouponService awardCouponService;
    @Autowired
    private FansAwardService fansAwardService;
    @Autowired
    private AwardSettingService awardSettingService;
    @Autowired
    private FansAuthService fansAuthService;

    /**
     * 新增助力
     * @param dto
     */
    @Transactional
    public void savesShareRecord(HelpRecordDTO dto, Long fansId) {
        HelpRecordEntity shareRecordEntity = BeanUtil.copyProperties(dto, HelpRecordEntity.class);
        // 用户发起助力记录ID不能为空
        if (ObjectUtils.isEmpty(shareRecordEntity.getActivityHelpId())) {
            throw new BizException("请求参数异常，请检查！");
        }
        shareRecordEntity.setToFansId(fansId);
        // 查询助力活动
        ActivityHelpEntity activityHelp = activityHelpService.getById(shareRecordEntity.getActivityHelpId());
        if (ObjectUtils.isEmpty(activityHelp)) {
            throw new BizException("活动分享异常");
        }
        ActivityEntity activityEntity = activityService.getById(activityHelp.getActivityId());
        if (ObjectUtils.isEmpty(activityEntity)) {
            throw new BizException("活动异常");
        }
        DateTime date = DateUtil.date();
        Date startTime = activityEntity.getStartTime();
        Date endTime = activityEntity.getEndTime();
        if (ObjectUtils.isEmpty(startTime) || startTime.getTime() > date.getTime()) {
            throw new BizException("当前活动还未开始");
        }
        if (ObjectUtils.isEmpty(endTime) || endTime.getTime() < date.getTime()) {
            throw new BizException("当前活动已结束");
        }

        // 不允许自己给自己助力
        if (activityHelp.getFansId().equals(shareRecordEntity.getToFansId())){
            throw new BizException("不能给自己助力哦，邀请好友帮您助力！");
        }
        // 查询被邀请用户是否帮该用户助力过
        LambdaQueryWrapper<HelpRecordEntity> shareRecordEntityGW = HelpRecordEntity.gw();
        shareRecordEntityGW.eq(HelpRecordEntity::getActivityHelpId,activityHelp.getActivityHelpId());
        shareRecordEntityGW.eq(HelpRecordEntity::getFansId,activityHelp.getFansId());
        shareRecordEntityGW.eq(HelpRecordEntity::getToFansId,shareRecordEntity.getToFansId());
        List<HelpRecordEntity> shareRecord = shareRecordService.list(shareRecordEntityGW);
        if (!shareRecord.isEmpty()){
            throw new BizException("您已帮该用户助力过，请勿重复助力！");
        }
        // 查询活动配置
        LambdaQueryWrapper<ActivityShareEntity> activityShareGW = ActivityShareEntity.gw();
        activityShareGW.eq(ActivityShareEntity::getActivityId,shareRecordEntity.getActivityId());
        ActivityShareEntity activityShareEntity = activityShareService.getOne(activityShareGW);

        LambdaQueryWrapper<HelpRecordEntity> gw = HelpRecordEntity.gw().eq(HelpRecordEntity::getToFansId, shareRecordEntity.getToFansId())
                .eq(HelpRecordEntity::getActivityId,activityHelp.getActivityId());
        if (activityShareEntity.getToShareMaxNum() == 1){
            List<HelpRecordEntity> share = shareRecordService.list(gw);
            if (!share.isEmpty()){
                throw new BizException("对不起，您的助力次数已用完！");
            }
        }else if (activityShareEntity.getToShareMaxNum() > 1) {
            if (activityShareEntity.getToSharePeriodType() > 0) {
                if (activityShareEntity.getToSharePeriodType() == 1) {
                    startTime = DateUtil.beginOfDay(date);
                    endTime = DateUtil.endOfDay(date);
                }else if (activityShareEntity.getToSharePeriodType() == 2) {
                    startTime = DateUtil.beginOfWeek(date);
                    endTime = DateUtil.endOfWeek(date);
                }else if (activityShareEntity.getToSharePeriodType() == 3) {
                    startTime = DateUtil.beginOfMonth(date);
                    endTime = DateUtil.endOfMonth(date);
                }
            }
            gw.between(HelpRecordEntity::getCreatedAt, startTime, endTime);
            long count = shareRecordService.count(gw);
            if (activityShareEntity.getToSharePeriodType() > 0 && count >= activityShareEntity.getToSharePeriodTimes()) {
                String type = activityShareEntity.getToSharePeriodType() == Constants.PERIOD.DAY ? "日" : activityShareEntity.getToSharePeriodType() == Constants.PERIOD.WEEK ? "周" : activityShareEntity.getToSharePeriodType() == Constants.PERIOD.MONTH ? "月" : "年";
                throw new BizException(String.format("对不起，您每%s助力次数已用完", type));
            }else if (count >= activityShareEntity.getToShareMaxNum()){
                throw new BizException("对不起，您的助力次数已用完");
            }
        }
        if (activityHelp.getCreatedAt().getTime() < startTime.getTime()) {
            throw new BizException("当前助力已结束");
        }

        // 分享成功标准：0无要求  1小程序新用户  2未参与过该活动的小程序用户  3新实名用户
        Integer shareSuccessStandard = activityShareEntity.getShareSuccessStandard();
        if (shareSuccessStandard != 0) {
            FansEntity fansEntity = fansService.getById(fansId);
            //用户实名信息
            FansAuthEntity fansAuth = fansAuthService.getOne(FansAuthEntity.gw()
                    .eq(FansAuthEntity::getFansId, fansId).eq(FansAuthEntity::getAgentNo, activityEntity.getAgentNo()));
            if (shareSuccessStandard == 1 && fansEntity.getCreatedAt().getTime() < startTime.getTime()) {
                throw new BizException("您不是新注册用户，不符合助力标准");
            }else if (shareSuccessStandard == 3 && (ObjectUtils.isEmpty(fansAuth) || ObjectUtils.isEmpty(fansAuth.getAuthTime()) || fansEntity.getCreatedAt().getTime() < startTime.getTime())) {
                throw new BizException("您不是新实名用户，不符合助力标准");
            }else if (shareSuccessStandard == 2) {
                LambdaQueryWrapper<ActivityHelpEntity> toUserGw = ActivityHelpEntity.gw().eq(ActivityHelpEntity::getActivityHelpId, activityHelp.getActivityHelpId()).eq(ActivityHelpEntity::getFansId, shareRecordEntity.getToFansId());
                List<ActivityHelpEntity> toUserHelp = activityHelpService.list(toUserGw);
                if (ObjectUtils.isNotEmpty(toUserHelp)) {
                    throw new BizException("您已参与该活动，不可再为他人助力");
                }
            }
        }

        Integer exchangeType = activityShareEntity.getExchangeType();
        if (2 != exchangeType){
            LambdaQueryWrapper<ActivityAwardEntity> activityAwardGW = ActivityAwardEntity.gw().eq(ActivityAwardEntity::getActivityId, shareRecordEntity.getActivityId());
            List<ActivityAwardEntity> activityAwardList = activityAwardService.list(activityAwardGW);
            if (activityAwardList.isEmpty()){
                throw new BizException("活动奖品配置异常");
            }
            Integer exchangeShareNum = activityAwardList.get(0).getExchangeShareNum();
            // 更新助力表当前助力人数和当前剩余助力人数
            if (activityHelp.getSuccessStandardNum() >= exchangeShareNum){
                throw new BizException("该用户已完成助力！");
            }
        }
        activityHelp.setSuccessStandardNum(activityHelp.getSuccessStandardNum() + 1);
        activityHelp.setTotalHelpNum(activityHelp.getTotalHelpNum() + 1);
        activityHelp.setSurplusSuccessNum(activityHelp.getSurplusSuccessNum() + 1);
        // 更新发起人记录（当前助力人数和当前剩余助力人数）
        activityHelpService.updateById(activityHelp);
        // 新增被邀记录
        FansUserEntity fansUserEntity = fansUserService.getBaseMapper().selectById(dto.getUserId());
        shareRecordEntity.setActivityHelpId(activityHelp.getActivityHelpId());
        shareRecordEntity.setIsConsume(0);
        shareRecordEntity.setIsSuccess(1);
        shareRecordEntity.setToFansId(fansId);
        shareRecordEntity.setAppId(fansUserEntity.getAppId());
        shareRecordEntity.setFansId(fansUserEntity.getFansId());
        shareRecordEntity.setCreatedAt(new Date());
        helpRecordMapper.insert(shareRecordEntity);
    }

    /**
     * 助力记录
     * @param helpRecordDTO
     * @return
     */
    public List<HelpRecordVO> details(HelpRecordDTO helpRecordDTO) {
        // 用户发起助力记录ID不能为空
        if (ObjectUtils.isEmpty(helpRecordDTO.getActivityHelpId())) {
            throw new BizException("请求参数异常，请检查！");
        }
        // 查询助力记录 根据用户发起的助力记录ID,并且状态为助力成功
            helpRecordDTO.setIsSuccess(1);
        log.info("查询助力记录:{}", JSONUtil.toJsonStr(helpRecordDTO));
        return helpRecordMapper.selectHelpRecordList(helpRecordDTO);
    }

    /**
     * 兑换消耗助力次数
     * @param helpRecordDTO
     * @return
     */
    @Transactional
    public void exchange(HelpRecordDTO helpRecordDTO, Long fansId, String agentNo) {
        // 用户发起助力记录ID不能为空
        if (ObjectUtils.isEmpty(helpRecordDTO.getActivityHelpId())) {
           throw new BizException("请求参数异常，请检查！");
        }
        if (ObjectUtils.isEmpty(helpRecordDTO.getActivityAwardId())) {
            throw new BizException("请选择要兑换的奖品");
        }

        ActivityHelpEntity fActivityHelp = fActivityHelpGetOne(helpRecordDTO.getActivityHelpId());
        if (ObjectUtils.isEmpty(fActivityHelp) || !fansId.equals(fActivityHelp.getFansId())){
            throw new BizException("非本人兑换!");
        }

        ActivityAwardEntity activityAwardEntity = activityAwardService.getById(helpRecordDTO.getActivityAwardId());
        if (ObjectUtils.isEmpty(activityAwardEntity) || ObjectUtils.isEmpty(activityAwardEntity.getExchangeShareNum())){
            throw new BizException("奖品异常");
        }

        ActivityShareEntity activityShareEntity = activityShareService.getOne(ActivityShareEntity.gw().eq(ActivityShareEntity::getActivityId, fActivityHelp.getActivityId()));
        if (ObjectUtils.isEmpty(activityShareEntity)) {
            throw new BizException("活动配置异常");
        }
        Integer exchangeType = activityShareEntity.getExchangeType();

        // 查询用户领取该卡券数量
        LambdaQueryWrapper<FansAwardEntity> fansAwardGw = FansAwardEntity.gw().eq(FansAwardEntity::getFansId, fansId)
                .eq(FansAwardEntity::getAwardId, activityAwardEntity.getAwardId())
                .eq(FansAwardEntity::getAwardType, activityAwardEntity.getAwardType());
        long count = fansAwardService.count(fansAwardGw);
        if (2 != exchangeType) {
            // 最大次数大于1
            if (activityShareEntity.getShareMaxNum() > 1) {
                // 判断周期性次数
                if (activityShareEntity.getSharePeriodType() > 0) {
                    DateTime date = DateUtil.date();
                    if (activityShareEntity.getSharePeriodType() == 1) {
                        fansAwardGw.between(FansAwardEntity::getCreatedAt, DateUtil.beginOfDay(date), DateUtil.endOfDay(date));
                    }else if (activityShareEntity.getSharePeriodType() == 2) {
                        fansAwardGw.between(FansAwardEntity::getCreatedAt, DateUtil.beginOfWeek(date), DateUtil.endOfWeek(date));
                    }else if (activityShareEntity.getSharePeriodType() == 3) {
                        fansAwardGw.between(FansAwardEntity::getCreatedAt, DateUtil.beginOfMonth(date), DateUtil.endOfMonth(date));
                    }
                    count = fansAwardService.count(fansAwardGw);
                    // 周期性次数大于
                    if (count > activityShareEntity.getSharePeriodTimes()) {
                        String type = activityShareEntity.getSharePeriodType() == Constants.PERIOD.DAY ? "日" : activityShareEntity.getSharePeriodType() == Constants.PERIOD.WEEK ? "周" : activityShareEntity.getSharePeriodType() == Constants.PERIOD.MONTH ? "月" : "年";
                        throw new BizException(String.format("您已达到每%s该奖品最大兑换限制", type));
                    }
                }else {
                    // 无周期性限制判断最大次数
                    if (count > activityShareEntity.getShareMaxNum()) {
                        throw new BizException("您已达到该奖品最大兑换限制");
                    }
                }
            }else {
                // 只能领一次
                if (count > 0) {
                    throw new BizException("您已兑换过该奖品，请勿重复兑换");
                }
            }
        }else {
            // 判断卡券奖品兑换次数限制校验
            if (Constants.AWARD.COUPON == activityAwardEntity.getAwardType()) {
                // 查询卡券
                AwardCouponEntity couponAwardEntity = awardCouponService.getById(activityAwardEntity.getAwardId());
                if (count >= couponAwardEntity.getEveryoneMaxNum()) {
                    throw new BizException("当前奖品已达到最大兑换限制，请兑换其他奖品");
                }
            }
        }

        if (fActivityHelp.getSurplusSuccessNum() < activityAwardEntity.getExchangeShareNum()){
            throw new BizException("助力用尽，请先去邀请好友助力！");
        }
        // 个人信息
//        LambdaQueryWrapper<FansUserEntity> fansOpenidUserGW = FansUserEntity.gw();
//        fansOpenidUserGW.eq(FansUserEntity::getFansId,fActivityHelp.getFansId());
//        FansUserEntity fansOpenidUser = fansUserService.getOne(fansOpenidUserGW);
        // 活动信息
        LambdaQueryWrapper<ActivityEntity> activityGW = ActivityEntity.gw();
        activityGW.eq(ActivityEntity::getActivityId,fActivityHelp.getActivityId());
        ActivityEntity activity = activityService.getOne(activityGW);
        AwardSettingEntity awardSettingEntity = awardSettingService.lambdaQuery().eq(AwardSettingEntity::getAwardId,activityAwardEntity.getAwardId()).eq(AwardSettingEntity::getAwardType,activityAwardEntity.getAwardType()).one();
        // 组装参数
        ActivityAwardAndSettingBo activityAwardAndSettingBo = new ActivityAwardAndSettingBo();
        activityAwardAndSettingBo.setAwardId(activityAwardEntity.getAwardId());
        activityAwardAndSettingBo.setAwardType(activityAwardEntity.getAwardType());
        activityAwardAndSettingBo.setRemark(activityAwardEntity.getRemark());
        activityAwardAndSettingBo.setIsOpenReceipt(awardSettingEntity.getIsOpenReceipt());
        activityAwardAndSettingBo.setEndTime(activity.getEndTime());
        if (Constants.AWARD.SCORE == activityAwardEntity.getAwardType()) {
            sendAwardService.sendScore(fansId, helpRecordDTO.getAppId(), activityAwardAndSettingBo, null, true, agentNo, fActivityHelp.getActivityId(), Constants.SCORE.ACTIVITY);
        }else {
            // 发放奖品
            sendAwardService.sendCouponOrGoods(fansId, helpRecordDTO.getAppId(), activityAwardAndSettingBo, activity.getPayAuthId(),null, true, null);
        }
        // 扣除积分
        fActivityHelp.setSurplusSuccessNum(fActivityHelp.getSurplusSuccessNum() - activityAwardEntity.getExchangeShareNum());
        activityHelpService.updateById(fActivityHelp);
        // 修改分享记录表消耗状态
        LambdaQueryWrapper<HelpRecordEntity> gw = HelpRecordEntity.gw().eq(HelpRecordEntity::getFansId, fansId).eq(HelpRecordEntity::getActivityHelpId, helpRecordDTO.getActivityHelpId())
                .eq(HelpRecordEntity::getIsSuccess, 1).eq(HelpRecordEntity::getIsConsume, 0).orderByAsc(HelpRecordEntity::getHelpRecordId)
                .last(" limit " + activityAwardEntity.getExchangeShareNum());
        HelpRecordEntity shareRecordEntity = new HelpRecordEntity();
        shareRecordEntity.setIsConsume(1);
        helpRecordMapper.update(shareRecordEntity, gw);
    }

    public ActivityHelpEntity fActivityHelpGetOne(Long activityHelpId){
        LambdaQueryWrapper<ActivityHelpEntity> fActivityHelpGW = ActivityHelpEntity.gw();
        fActivityHelpGW.eq(ActivityHelpEntity::getActivityHelpId, activityHelpId);
        return activityHelpService.getOne(fActivityHelpGW);
    }
}
